package com.example.farmrental.service;

import com.example.farmrental.dto.PageResponse;
import com.example.farmrental.dto.RentalOrderDto;
import com.example.farmrental.entity.RentalOrder;
import com.example.farmrental.entity.RentalOrderItem;
import com.example.farmrental.entity.Machinery;
import com.example.farmrental.repository.RentalOrderItemRepository;
import com.example.farmrental.repository.RentalOrderRepository;
import com.example.farmrental.repository.MachineryRepository;
import com.example.farmrental.repository.SetmealRepository;
import com.example.farmrental.repository.CustomerRepository;
import com.example.farmrental.entity.Customer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Predicate;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * 订单业务服务：分页查询、详情、创建、更新状态、删除、DTO 转换等
 */
@Service
public class RentalOrderService {

    @Autowired
    private RentalOrderRepository orderRepository;

    @Autowired
    private RentalOrderItemRepository itemRepository;

    @Autowired
    private MachineryRepository machineryRepository;

    @Autowired
    private SetmealRepository setmealRepository;

    @Autowired
    private CustomerRepository customerRepository;

    /**
     * 分页查询订单（可按状态、订单号、手机号、下单日期过滤）
     */
    public PageResponse<RentalOrderDto> list(int page, int size, String status, String orderNo, String phone, String orderDate) {
        Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "orderTime"));

        Specification<RentalOrder> spec = (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (status != null && !status.isEmpty()) {
                predicates.add(cb.equal(root.get("status"), status));
            }
            if (orderNo != null && !orderNo.isEmpty()) {
                predicates.add(cb.like(root.get("orderNo"), "%" + orderNo + "%"));
            }
            if (phone != null && !phone.isEmpty()) {
                predicates.add(cb.like(root.get("phone"), "%" + phone + "%"));
            }
            if (orderDate != null && !orderDate.isEmpty()) {
                try {
                    LocalDate d = LocalDate.parse(orderDate);
                    LocalDateTime start = d.atStartOfDay();
                    LocalDateTime end = d.atTime(LocalTime.MAX);
                    predicates.add(cb.between(root.get("orderTime"), start, end));
                } catch (Exception ignored) {}
            }
            return cb.and(predicates.toArray(new Predicate[0]));
        };

        Page<RentalOrder> pageData = orderRepository.findAll(spec, pageable);
        List<RentalOrderDto> content = pageData.getContent().stream().map(this::toDto).collect(Collectors.toList());
        return new PageResponse<>(content, pageData.getTotalElements(), page, size);
    }

    /** 获取订单实体 */
    public Optional<RentalOrder> findById(Long id) { return orderRepository.findById(id); }

    /** 获取订单详情（DTO） */
    public Optional<RentalOrderDto> getDtoById(Long id) {
        return orderRepository.findById(id).map(this::toDto);
    }

    /** 创建订单 */
    public RentalOrder createOrder(RentalOrderDto dto) {
        RentalOrder order = new RentalOrder();
        order.setOrderNo(dto.orderNo != null ? dto.orderNo : genOrderNo());
        // 默认状态：待接单
        order.setStatus(dto.status != null ? dto.status : "待接单");
        order.setUsername(dto.username);
        order.setPhone(dto.phone);
        order.setAddress(dto.address);
        order.setOrderTime(dto.orderTime != null ? dto.orderTime : LocalDateTime.now());
        order.setStartDate(dto.startDate);
        order.setEndDate(dto.endDate);
        // 金额兜底
        order.setAmount(dto.amount != null ? dto.amount : java.math.BigDecimal.ZERO);
        order.setSetmealId(dto.setmealId);

        // 客户档案：按手机号去重，若不存在则新增；若存在但无姓名则补全，并将 customerId 写入订单
        if (dto.phone != null && !dto.phone.trim().isEmpty()) {
            Long cid;
            java.util.Optional<Customer> exist = customerRepository.findFirstByPhone(dto.phone);
            if (exist.isPresent()) {
                Customer c = exist.get();
                if ((c.getName() == null || c.getName().trim().isEmpty()) && dto.username != null && !dto.username.trim().isEmpty()) {
                    c.setName(dto.username);
                    c = customerRepository.save(c);
                }
                cid = c.getId();
            } else {
                Customer c = new Customer();
                c.setPhone(dto.phone);
                c.setName(dto.username);
                c = customerRepository.save(c);
                cid = c.getId();
            }
            order.setCustomerId(cid);
        } else {
            // 兜底：若未提供手机号，仍确保有一个客户记录（使用匿名占位）
            Customer c = new Customer();
            c.setPhone("unknown");
            c.setName(dto.username);
            c = customerRepository.save(c);
            order.setCustomerId(c.getId());
        }

        if (dto.machineryList != null) {
            List<RentalOrderItem> items = new ArrayList<>();
            for (RentalOrderDto.Item it : dto.machineryList) {
                RentalOrderItem item = new RentalOrderItem();
                item.setOrder(order);
                // 若提供了machineryId，建立关联并以库里的名称为准
                if (it.machineryId != null) {
                    Machinery m = machineryRepository.findById(it.machineryId).orElse(null);
                    if (m != null) {
                        item.setMachinery(m);
                        item.setMachineryName(m.getName());
                    } else {
                        item.setMachineryName(it.name);
                    }
                } else {
                    item.setMachineryName(it.name);
                }
                // 若未传数量，默认 1（前端 UI 不展示数量）
                item.setQuantity(it.quantity != null ? it.quantity : 1);
                item.setPrice(it.price);
                items.add(item);
            }
            order.setItems(items);
        }
        // 若金额为空或<=0，按明细或套餐自动计算
        if (order.getAmount() == null || order.getAmount().compareTo(java.math.BigDecimal.ZERO) <= 0) {
            if (order.getSetmealId() != null) {
                setmealRepository.findById(order.getSetmealId()).ifPresent(s -> {
                    if (s.getTotalPrice() != null) order.setAmount(s.getTotalPrice());
                });
            } else if (order.getItems() != null && !order.getItems().isEmpty()) {
                java.math.BigDecimal sum = java.math.BigDecimal.ZERO;
                for (RentalOrderItem it : order.getItems()) {
                    java.math.BigDecimal p = it.getPrice() != null ? it.getPrice() : java.math.BigDecimal.ZERO;
                    int q = it.getQuantity() != null ? it.getQuantity() : 1;
                    sum = sum.add(p.multiply(java.math.BigDecimal.valueOf(q)));
                }
                order.setAmount(sum);
            }
        }
        return orderRepository.save(order);
    }

    /** 更新订单状态 */
    public Optional<RentalOrder> updateStatus(Long id, String status) {
        return orderRepository.findById(id).map(o -> {
            o.setStatus(status);
            return orderRepository.save(o);
        });
    }

    /** 删除订单 */
    public void delete(Long id) {
        orderRepository.deleteById(id);
    }

    /** 实体转 DTO */
    private RentalOrderDto toDto(RentalOrder order) {
        RentalOrderDto d = new RentalOrderDto();
        d.id = order.getId();
        d.orderNo = order.getOrderNo();
        d.status = order.getStatus();
        d.username = order.getUsername();
        d.phone = order.getPhone();
        d.address = order.getAddress();
        d.orderTime = order.getOrderTime();
        d.startDate = order.getStartDate();
        d.endDate = order.getEndDate();
        d.amount = order.getAmount();
        d.setmealId = order.getSetmealId();
        if (order.getItems() != null) {
            d.machineryList = order.getItems().stream().map(it -> {
                RentalOrderDto.Item di = new RentalOrderDto.Item();
                di.id = it.getId();
                di.machineryId = it.getMachinery() != null ? it.getMachinery().getId() : null;
                String name = it.getMachineryName();
                if (di.machineryId == null && (name == null || name.isEmpty())) {
                    // 回填：根据名称尝试关联库中农机
                    if (name != null) {
                        Machinery m = machineryRepository.findFirstByName(name);
                        if (m != null) di.machineryId = m.getId();
                    }
                }
                if (it.getMachinery() != null) {
                    name = it.getMachinery().getName();
                }
                di.name = name;
                di.quantity = it.getQuantity();
                di.price = it.getPrice();
                return di;
            }).collect(Collectors.toList());
        }
        // 若来源于套餐，回填套餐名称
        if (order.getSetmealId() != null) {
            d.setmealId = order.getSetmealId();
            setmealRepository.findById(order.getSetmealId()).ifPresent(s -> d.setmealName = s.getName());
        }
        return d;
    }

    /** 生成订单号：RO + 时间戳(yyyyMMddHHmmss) + 4位随机 */
    private String genOrderNo() {
        String ts = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").format(LocalDateTime.now());
        String rand = UUID.randomUUID().toString().replace("-", "").substring(0, 4).toUpperCase();
        return "RO" + ts + rand;
    }
}
